/*
 * Copyright (C) 2023 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package app.cash.redwood.treehouse

import android.view.Choreographer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

/**
 * A [FrameClock] that sends frames using [Choreographer].
 */
internal class AndroidChoreographerFrameClock private constructor(
  private val choreographer: Choreographer,
  private val scope: CoroutineScope,
  private val dispatchers: TreehouseDispatchers,
) : FrameClock {

  override fun requestFrame(appLifecycle: AppLifecycle) {
    choreographer.postFrameCallback { frameTimeNanos ->
      scope.launch(dispatchers.zipline) {
        appLifecycle.sendFrame(frameTimeNanos)
      }
    }
  }

  override fun close() {
  }

  class Factory : FrameClock.Factory {
    private val choreographer = Choreographer.getInstance()
    override fun create(
      scope: CoroutineScope,
      dispatchers: TreehouseDispatchers,
    ) = AndroidChoreographerFrameClock(choreographer, scope, dispatchers)
  }
}
